package com.goldsprite.gameframeworks.simplephys.collis;

import com.badlogic.gdx.math.MathUtils;
import com.goldsprite.gameframeworks.simplephys.shape.PhysCircle;
import com.goldsprite.gameframeworks.simplephys.shape.PhysRect;
import com.goldsprite.gameframeworks.utils.math.Vector2;

public class CollisionUtils {
	private static final CollisionResult tmpCollisionResult = new CollisionResult();
	public static boolean isResetCalc = true;
	public static final float safeDistance = 0f;

	// 注册所有碰撞检测器
	public static final RectRectCollisionDetector rectRectDetector = new RectRectCollisionDetector();
	public static final CircleCircleCollisionDetector circleCircleDetector = new CircleCircleCollisionDetector();
	public static final CircleRectCollisionDetector circleRectDetector = new CircleRectCollisionDetector();


	//基本方法=========================================
	// 矩形与矩形碰撞
	public static boolean calculateCollision(PhysRect a, PhysRect b, CollisionResult result) {
		return rectRectDetector.calculateCollision(a, b, result);
	}

	// 圆形与圆形碰撞
	public static boolean calculateCollision(PhysCircle a, PhysCircle b, CollisionResult result) {
		return circleCircleDetector.calculateCollision(a, b, result);
	}

	/**
	 * 圆形与矩形碰撞检测
	 */
	public static boolean calculateCollision(PhysCircle circle, PhysRect rect, CollisionResult result) {
		return circleRectDetector.calculateCollision(circle, rect, result);
	}

	/**
	 * 矩形与圆形碰撞检测（交换参数顺序）
	 */
	public static boolean calculateCollision(PhysRect rect, PhysCircle circle, CollisionResult result) {
		boolean collided = circleRectDetector.calculateCollision(circle, rect, result);
		if (collided) {
			result.normal.scl(-1);
		}
		return collided;
	}

	public static boolean ccdCollision2(Vector2 moved, PhysCircle circle, PhysRect rect, CollisionResult result) {
		return circleRectDetector.ccdCollision2(moved, circle, rect, result);
	}

	public static boolean ccdCollision2(Vector2 moved, PhysRect rect, PhysCircle circle, CollisionResult result) {
		boolean collided = circleRectDetector.ccdCollision2(moved, circle, rect, result);
		if (collided) {
			result.normal.scl(-1);
		}
		return collided;
	}


	//便捷方法=========================================
	/**
	 * 便捷方法：创建新的CollisionResult并进行检测
	 */
	public static CollisionResult calculateCollision(PhysRect a, PhysRect b) {
		CollisionResult result = tmpCollisionResult;
		result.reset();
		rectRectDetector.calculateCollision(a, b, result);
		return result.collided ? result : null;
	}

	/**
	 * 便捷方法：圆形碰撞检测使用临时结果
	 */
	public static CollisionResult calculateCollision(PhysCircle a, PhysCircle b) {
		CollisionResult result = tmpCollisionResult;
		result.reset();
		circleCircleDetector.calculateCollision(a, b, result);
		return result.collided ? result : null;
	}

	/**
	 * 便捷方法：圆形与矩形碰撞检测使用临时结果
	 */
	public static CollisionResult calculateCollision(PhysCircle circle, PhysRect rect) {
		CollisionResult result = tmpCollisionResult;
		result.reset();
		circleRectDetector.calculateCollision(circle, rect, result);
		return result.collided ? result : null;
	}

	public static CollisionResult calculateCollision(PhysRect rect, PhysCircle circle) {
		CollisionResult result = tmpCollisionResult;
		result.reset();
		calculateCollision(rect, circle, result);
		return result.collided ? result : null;
	}


	// 快速检查方法===================
	public static boolean checkCollision(PhysRect a, PhysRect b) {
		return !(a.x > b.x + b.width ||
			a.x + a.width < b.x ||
			a.y > b.y + b.height ||
			a.y + a.height < b.y);
	}

	/**
	 * 检查两个圆形是否碰撞（仅返回布尔值，最高效）
	 */
	public static boolean checkCollision(PhysCircle a, PhysCircle b) {
		float dx = b.x - a.x;
		float dy = b.y - a.y;
		float distanceSquared = dx * dx + dy * dy;
		float radiusSum = a.radius + b.radius;
		return distanceSquared <= radiusSum * radiusSum;
	}

	public static boolean checkCollision(PhysCircle circle, PhysRect rect) {
		float closestX = MathUtils.clamp(circle.x, rect.x, rect.x + rect.width);
		float closestY = MathUtils.clamp(circle.y, rect.y, rect.y + rect.height);
		float dx = circle.x - closestX;
		float dy = circle.y - closestY;
		return (dx * dx + dy * dy) <= circle.radius * circle.radius;
	}

	public static boolean checkCollision(PhysRect rect, PhysCircle circle) {
		return checkCollision(circle, rect); // 复用逻辑
	}
}
